package com.goldsprite.gdxcore.utils.sorts;

import com.badlogic.gdx.utils.Array;

public class EntitySort<T extends IEntitySortable> {
	private Array<T> ents;
	private final boolean ascending; // 排序方向（true 为正向，从小到大；false 为反向）

    public EntitySort(Array<T> ents, boolean ascending) {
        this.ents = ents;
        this.ascending = ascending;
        // 初始化时按配置排序
		sort();
    }
	
	/**
	 * 对实体数组进行排序 这里默认TimSort
	 */
	public void sort() {
        ents.sort((a, b) -> compare(a.z(), b.z()));
		// 更新所有实体的缓存索引
		for (int i = 0; i < ents.size; i++) {
			ents.get(i).setCachedIndex(i);
		}
	}
	
	/**
     * 针对单个实体调整位置, 使用二分排序
     */
    public void sort(T ent) {
		sort();
		/*
        // 从数组中移除该实体
        ents.removeValue(ent, true);

        // 找到正确的位置
        int index = binarySearchInsertIndex(ent.z());

        // 插入到目标位置
        ents.insert(index, ent);
		
		ent.setCachedIndex(index);*/
    }

	/**
	 * 添加实体，不自动排序
	 */
	public void add(T entity) {
		ents.add(entity);
	}

	/**
	 * 手动触发排序
	 */
	public void triggerSort() {
		sort();
	}

	/**
	 * 获取排序后的实体数组
	 */
	public Array<T> getSortedEntities() {
		return ents;
	}
	
	public int indexOf(T ent){
		return ents.indexOf(ent, true);
	}
	
	public int binarySearchInsertIndex(float z) {
		Array<T> array = ents;
		int low = 0, high = array.size - 1;

		while (low <= high) {
			int mid = (low + high) >>> 1; // 等价于 (low + high) / 2
			float midZ = array.get(mid).z();

			if (midZ < z) {
				low = mid + 1;
			} else if (midZ > z) {
				high = mid - 1;
			} else {
				return mid; // 找到精确位置
			}
		}
		return low; // 返回插入点
	}
	
	// 比较两个 z 值，根据 ascending 控制排序方向
    private int compare(float z1, float z2) {
        return ascending ? Float.compare(z1, z2) : Float.compare(z2, z1);
    }
	
	
	public static void main(String[] args) {
        Array<GameEntity> entities = new Array<>();
		
        // 创建排序器
        EntitySort<GameEntity> sorter = new EntitySort<>(entities, false);
		
        // 创建实体数组
        entities.add(new GameEntity(sorter, 5.0f));
        entities.add(new GameEntity(sorter, 1.0f));
        entities.add(new GameEntity(sorter, 3.0f));

        printEntities(sorter);
		
        // 初始排序
        sorter.sort();
        System.out.println("Sorted Entities (Initial):");
        printEntities(sorter);

        // 添加新实体
        GameEntity newEntity = new GameEntity(sorter, 2.0f);
        sorter.add(newEntity);

        // 手动触发排序
        sorter.sort(newEntity);
        System.out.println("Sorted Entities (After Adding):");
        printEntities(sorter);

        // 更新某个实体的 z 值
		System.out.println("更新ent: "+newEntity.z+" -> 6.0");
        newEntity.setZ(6.0f);

        // 手动触发排序
        sorter.sort(newEntity);
        System.out.println("Sorted Entities (After Update):");
        printEntities(sorter);
    }

    private static void printEntities(EntitySort<GameEntity> sorter) {
        for (GameEntity entity : sorter.getSortedEntities()) {
            System.out.println("Entity Z: " + entity.z());
        }
    }

	
	static class GameEntity implements IEntitySortable {
		private float z;
		private EntitySort<GameEntity> sorter;
		private int cachedIndex;

		public GameEntity(EntitySort<GameEntity> sorter, float z) {
			setSorter(sorter);
			this.z = z;
		}

		@Override
		public float z() {
			return z;
		}

		public void setZ(float newZ) {
			this.z = newZ; // 直接更新 z 值
		}

		public void setSorter(EntitySort<GameEntity> sorter){
			this.sorter = sorter;
		}
		
		public EntitySort<GameEntity> getSorter() {
			return sorter;
		}
		
		public void setCachedIndex(int index){
			this.cachedIndex = index;
		}
	}

}

